-------------------------------------------------------------------------------
-- RTSAI - Real-Time Strategy engine for AI research
-- Copyright(C) 2006 DIMAp-UFRN, licensed under LGPL
--
-- RTSAI application example
-------------------------------------------------------------------------------

last = 0

Game {
    -- PLAYERS ----------------------------------------------------------------
    players = {
        joao = { civilization = "poti", strategy = "my_strategy" },
        maria = { civilization = "poti", strategy = "my_strategy" }
    },

    -- WORLD ------------------------------------------------------------------
    -- for the moment, it's just temporary data
    world = {
        width = 512,
        height = 512,
        grid_size = 8,

        raw_data = {
            -- etc
        },

        resources = {
            -- etc
        }
    },

    -- EVENTS -----------------------------------------------------------------
    -- the events that may happen during the game
    --
    events = {
        -- This is a random event (for testing purposes).
        -- The function is used for checking if the event happenned in the game.
        -- If the function returns nothing, then the event didn't happen. If it
        -- did happen, then the function must return a table containing the event
        -- data. This data can be consulted in the callbacks in the states that
        -- are listening to the event.
        random_event = function ()
            local d = math.random ()
            if d < 0.005 then  -- the event will happen only when d < 0.004
                return { random = d }  -- the event data will be the random number
            end
        end
    },

    -- ACTIONS ----------------------------------------------------------------
    -- the actions that unit may perform
    actions = {
        move = {
            -- evaluate if the action can be performed
            precondition = function ( self, unit )
                -- if it is blocked return false
                return true
            end,

            -- action's execution
            execute = function ( self, unit, elapsed_time )
                local obst = game:get_objs()
                local avoid_obst = unit:steerToAvoidObjects ( 2.5, obst )
                -- if avoid_obst == rtsai.Vector3D.zero then
                if avoid_obst.x == 0 and avoid_obst.y == 0 and avoid_obst.z == 0 then
                    unit:applySteeringForce ( self.steer, elapsed_time )
                else
                    unit:applySteeringForce ( avoid_obst, elapsed_time )
                end
            end
        },

        change_state = {
            execute = function ( self, unit, elapsed_time )
                if self.state then
                    unit:change_state ( self.state:new() )
                end
            end
        }
    },

    -- OBJECTS ----------------------------------------------------------------
    -- the type of objects in the game. The objects themselves need to be
    -- created in the init function (according to the type defined here).
    objects = {
        stone   = circ (2, true),      -- a circular object with radius 3. It is an obstacle
        house   = rect (10, 5, true),  -- a rectangular object with dimensions 10x5. It is an obstacle
        target1 = circ (0.5, false),     -- a circular object with radius 1. It is not an obstacle
        target2 = circ (0.5, false)      -- a circular object with radius 1. It is not an obstacle
    },

    -- AUXILIARY FUNCTIONS ----------------------------------------------------

    -- Game initialization.
    init = function ( self )

        -- obstacles initialization (10 obstacles)
        for obs_id = 1, 5 do
            local x = math.random ( -10, 10 )
            local z = math.random ( -10, 10 )
            local s = game.objects.stone:new ( rtsai.Vector3D:new (x, 0, z) )
            self:add_obj ( s )
        end

        local base1 = game.objects.target1:new ( rtsai.Vector3D:new ( 10, 0, 10 ) )
        local base2 = game.objects.target2:new ( rtsai.Vector3D:new ( -10, 0, -10 ) )

        self:add_obj ( base1 )
        self:add_obj ( base2 )


        -- random position to seeker unit
        local x = math.random ( -10, 10 )
        local z = math.random ( -10, 10 )

        -- seeker unit
        local player1 = self:get_player ( "maria" )
        local u1_1 = player1:createUnit(poti.warrior, seeking_the_flag)
        u1_1:setPosition ( rtsai.Vector3D:new ( x, 0, z ) )

        -- chaser units
        --[
        local player2 = self:get_player ( "joao" )

        local u2_1 = player2:createUnit(poti.warrior, chasing)
        local u2_2 = player2:createUnit(poti.warrior, chasing)
        local u2_3 = player2:createUnit(poti.warrior, chasing)
        local u2_4 = player2:createUnit(poti.warrior, chasing)

        u2_1:setPosition ( rtsai.Vector3D:new ( x+5, 0, z+5 ) )
        u2_2:setPosition ( rtsai.Vector3D:new ( x+5, 0, z-5 ) )
        u2_3:setPosition ( rtsai.Vector3D:new ( x-5, 0, z+5 ) )
        u2_4:setPosition ( rtsai.Vector3D:new ( x-5, 0, z-5 ) )
        --]]
    end
}
